'use strict';
// Copyright 2014 Blueant Inc. All Rights Reserved.

/**
 * @fileoverview 建筑
 * @author sundbcn@gmail.com (sun debing)
 */

var mongoose = require('mongoose');
var moment = require('moment');
var _ = require('lodash');
var soldierType = require('../consts/soldierType');
var buildType = require('../consts/buildType');
var buildUseType = require('../consts/buildUseType');
var buildCheck = require('../libs/buildCheck');
var buildTypeUtil = require('../util/buildTypeUtil');
var dataApi = require('../libs/dataApi');
var buildScheduleSchema = require('./build/buildScheduleSchema');
var buildItemSchema = require('./build/buildItemSchema');
var buildConf = require('../config/buildConf');
var buildMgr = require('../mgr/buildMgr.js');
var constantUtil = require('../util/constantUtil.js');
var buildType = require('../consts/buildType.js');
var ObjectId = mongoose.Types.ObjectId;

///////////////////////////////////////////////////////////
/**
 * build schema.
 * @type {mongoose}
 */

/**
 * 初始化废墟列表
 * @return {[type]} [description]
 */
var _initRuin = function () {
    var ruin_list = [];
    dataApi.ruin.each(function (value, key) {
        ruin_list.push(key);
    });
    return ruin_list;
};

/**
 * 初始化道路
 * @return {[type]} [description]
 */
var _initRoad = function () {
    var road_list = [];
    dataApi.road.each(function (value) {
        road_list.push(value.road_id);
    });
    return road_list;
};

var _initEcoBuild = function () {
    var build_list = [];

    // 添加其他初始的建筑
    dataApi.economy_build.each(function (build_item_conf, cell) {
        build_list.push({
            _id: new ObjectId(),
            build_id: build_item_conf.build_id,
            lv: build_item_conf.lvl
        });
    });

    return build_list;
};

var _initDefBuild = function () {
    var build_list = [];

    // 添加其他初始的建筑
    dataApi.defense_build.each(function (build_item_conf, cell) {
        var build_type = buildTypeUtil.getBuildType(build_item_conf.build_id);
        if (build_type == buildType.WALL) {
            build_list.push({
                _id: new ObjectId(),
                build_id: build_item_conf.build_id,
                lv: 1,
                cell: cell,
                soldier_list: []
            });
        } else {
            build_list.push({
                _id: new ObjectId(),
                build_id: build_item_conf.build_id,
                lv: 1,
                cell: cell
            });
        }
    });

    return build_list;
};

var _initTime = function () {
    return moment().unix();
};

var buildSchema = new mongoose.Schema({
    // 角色id
    role_id: {
        type: Number,
        required: true,
        unique: true,
        index: true
    },

    // 建筑升级排程
    build_schedule_list: [buildScheduleSchema],

    // 经济类建筑
    eco_build_list: {
        type: [buildItemSchema],
        default: _initEcoBuild
    },

    // 防御类建筑
    def_build_list: {
        type: [buildItemSchema],
        default: _initDefBuild
    },

    // 背包防御类建筑列表
    bag_def_build_list: {
        type: [buildItemSchema]
    },

    // 道路
    road_list: {
        type: [Number],
        default: _initRoad
    },

    // 地图上面的废墟
    ruin_list: {
        type: [Number],
        default: _initRuin
    },

    // 建筑战力
    build_power: {
        type: Number,
        default: 0
    },

    // 城门士兵战力
    wall_soldier_power: {
        type: Number,
        default: 0
    },

    // 建筑道具消耗卡时间
    consume_quick: {
        type: Number,
        default: _initTime
    },

    // 建筑道具消耗卡百分比
    consume_percentage: {
        type: Number,
        default: 0
    }
});

buildSchema.pre('save', function (next) {
    this.increment();
    if (!this.isNew && !!this.isModified()) {
        this.pushModify();
    }
    next();
});

/**
 * 推送到客户端
 * @return {[type]} [description]
 */
buildSchema.methods.push = function () {
    this.pushModify();
};

/**
 * 推送修改
 * @return {[type]} [description]
 */
buildSchema.methods.pushModify = function () {
    buildMgr.sendBuildChanged(
        this.role_id,
        this.getLastChange(),
        function (err, fails) {
            if (err) {
                console.error('send role message error: %j, fail ids: %j', err, fails);
                return;
            }
        }
    );
};

buildSchema.methods.getLastChange = function () {
    return this.toJSON();
};

if (!buildSchema.options.toJSON) {
    buildSchema.options.toJSON = {};
}

/* jshint unused:false */
buildSchema.options.toJSON.transform = function (doc, ret) {
    delete ret.role_id;
    delete ret._id;
    delete ret.__v;
};

/**
 * 获取道具卡加速时间
 * @param  {[type]} build_id [description]
 * @return {[type]}          [description]
 */
buildSchema.methods.getConsumeTime = function () {
    return this.consume_quick;
};

/**
 * 加速队列   (联盟帮助专用函数)
 * @param  {[type]} build_id [description]
 * @return {[type]}          [description]
 */
buildSchema.methods.quick_schedule = function (build_id) {
    var value = constantUtil.value('union_help_time_per');
    _.some(this.build_schedule_list, function (item) {
        if (item.build_id == build_id) {
            var unix_end_time = moment(item.end_time).unix();
            var time = unix_end_time - moment().unix();
            var sub_time = parseInt(time * (1 - value / 100));
            item.end_time = moment().add(sub_time, 's');
            return true;
        }
    });
};

/**
 * 获取道具卡加速百分比值
 * @param  {[type]} build_id [description]
 * @return {[type]}          [description]
 */
buildSchema.methods.getConsumePercentage = function () {
    return this.consume_percentage;
};

/**
 * 设置加速道具卡时间和百分比
 * @param  {[type]} build_id [description]
 * @return {[type]}          [description]
 * // consume_id: 5001601
 */
buildSchema.methods.setConsumeTime = function (consume_id) {
    var consum_conf = dataApi.consume.findById(consume_id);
    if (!consum_conf) {
        console.error('build  consume error --------------------');
        return;
    }

    var now_time = moment().unix();
    if (this.consume_quick >= now_time) {
        if (this.consume_percentage !== consum_conf.value) {
            this.consume_quick = now_time + consum_conf.time;
        } else {
            this.consume_quick += consum_conf.time;
        }
    } else {
        this.consume_quick = now_time + consum_conf.time;
        this.consume_percentage = consum_conf.value;
    }
};

/**
 * 当个建筑类型在背包建筑，和当前建筑中的总个数
 * @param  {[type]} build_id [description]
 * @return {[type]}          [description]
 */
buildSchema.methods.isOnlyTypeDefBuildMax = function (build_type) {
    var now_build_num = 0;
    var bag_build_num = 0;
    var only_type_total_max_num = this.getDefBuildMaxNum(build_type);
    var def_build_list_num = this.getDefBuildList();
    _.each(def_build_list_num, function (value) {
        var build_type1 = parseInt(value.build_id / 100);
        if (build_type1 == build_type) {
            now_build_num++;
        }
    });

    var bag_build_list_num = this.getBagDefBuidingList();
    _.each(bag_build_list_num, function (value1) {
        var build_type2 = parseInt(value1.build_id / 100);
        if (build_type2 == build_type) {
            bag_build_num++;
        }
    });

    return now_build_num + bag_build_num;
};

/**
 * 把防御建筑移到背包中
 * @param  {[type]} build_id [description]
 * @return {[type]}          [description]
 */
buildSchema.methods.pullDefBuild = function (build_id) {
    var remove_item = this.getBuild(build_id);
    if (!remove_item) {
        return false;
    } else {
        remove_item.remove();
        return remove_item;
    }
};

buildSchema.methods.pushBagDefBuild = function (build_item) {
    if (!build_item) {
        return false;
    } else {
        this.bag_def_build_list.push({
            build_id: build_item.build_id,
            lv: build_item.lv,
            star: build_item.star,
            build_exp: build_item.build_exp
        });
        return true;
    }
};
buildSchema.methods.pushDefBuild = function (build_item) {
    if (!build_item) {
        return false;
    } else {
        this.def_build_list.push(build_item);
        return true;
    }
};
buildSchema.methods.isBagDefBuild = function (build_id) {
    var list = [];
    list = this.getBagDefBuidingList();
    for (var i = 0; i < list.length; i++) {
        var item_build_id = list[i];
        if (item_build_id.build_id == build_id) {
            return true;
        }
    }
    return false;
};
buildSchema.methods.isDefBuild = function (build_id) {
    var list = [];
    list = this.getDefBuildList();
    for (var i = 0; i < list.length; i++) {
        var item_build_id = list[i];
        if (item_build_id.build_id == build_id) {
            return true;
        }
    }
    return false;
};
/**
 * 获取背包建筑列表
 * @param  {[type]} build_id [description]
 * @return {[type]}          [description]
 */
buildSchema.methods.getBagDefBuidingList = function () {
    return this.bag_def_build_list;
};

/**
 * 防御放置功能
 * @param  {[type]} build_id [description]
 * @return {[type]}          [description]
 */
buildSchema.methods.dischargeDefBuiding = function (cell) {
    var def_list = this.getDefBuildList();
    var item = {};
    for (var i = 0; i < def_list.length; i++) {
        item = def_list[i];
        if (item.cell == cell) {
            // item.remove();
            return item;
        }
    }
    return false;
};

/**
 * 移除背包建筑
 * @param  {[type]} build_id [description]
 * @return {[type]}          [description]
 */
buildSchema.methods.removeBagDefBuilding = function (build_id) {
    var item_def_build = {};
    var push_list = [];
    var build_item = this.getBagDefBuidingItem(build_id);

    if (build_item === undefined) {
        return false;
    }

    // 移除背包中建筑
    this.bag_def_build_list.pull(build_item);
    return build_item;
};

/*
 * 添加防御建筑(这个方法，只适合从建筑背包中移出到防御列表)
 */
buildSchema.methods.addDefBuildTwo = function (build_id, build_item, cell) {
    var push_list = [];
    var build_type = parseInt(build_id / 100);
    var build_num = this.getBuildNum(build_type);
    var nexus_lvl = this.getBuildByType(buildType.NEXUS).getLv();
    var max_num = this.getDefBuildMaxNum(build_type);

    if (build_num >= max_num) {
        return false;
    }
    push_list.push({
        build_id: build_id,
        lv: build_item.lv,
        star: build_item.star,
        build_exp: build_item.build_exp,
        cell: cell
    });

    this.def_build_list.push(push_list[0]);
    return true;
};

/**
 * 获取背包中建筑item
 * @param  {[type]} build_id [description]
 * @return {[type]}          [description]
 */
buildSchema.methods.getBagDefBuidingItem = function (build_id) {
    for (var i = 0; i < this.bag_def_build_list.length; i++) {
        var item = this.bag_def_build_list[i];
        if (build_id == item.build_id) {
            return item;
        }
    }
};

/*
 * 添加防御建筑
 */
buildSchema.methods.addDefBuild = function (build_type, cell, lv) {
    lv = lv || 0;
    var now_build_num = 0;
    var bag_build_num = 0;

    // 建筑列表最大上限
    var nexus_lvl = this.getBuildByType(buildType.NEXUS).getLv();
    var conf_max_build_def_num = buildConf.getBuildTotalNum(nexus_lvl);
    var now_build_def_num = this.getDefBuildList().length;

    if (now_build_def_num >= conf_max_build_def_num) {
        return false;
    }

    // 建筑id
    var build_id = buildTypeUtil.getBuildId(build_type, this.getDefBuildId(build_type) + 1);

    this.def_build_list.push({
        build_id: build_id,
        cell: cell,
        lv: lv
    });

    return build_id;
};

/**
 * 获取背包中建筑库存
 * @param  {[type]} build_id [description]
 * @return {[type]}          [description]
 */
buildSchema.methods.getBagDefBuidingStock = function (build_type) {
    var stock = 0;
    for (var i = 0; i < this.bag_def_build_list.length; i++) {
        var build_id = this.bag_def_build_list[i].build_id;
        var build_type_stock = parseInt(build_id / 100);
        if (build_type_stock == build_type) {
            stock++;
        }
    }
    return stock;
};

/**
 * 获取建筑
 * @param  {[type]} build_id [description]
 * @return {[type]}          [description]
 */
buildSchema.methods.getBuild = function (build_id) {
    var build_type = buildTypeUtil.getBuildType(build_id);
    var build_use_type = buildConf.getBuildUseType(build_type);
    if (!build_use_type) {
        return null;
    }
    var build_list = this.getBuildList(build_use_type);
    for (var i = 0; i < build_list.length; i++) {
        var build = build_list[i];
        if (build.build_id == build_id) {
            return build;
        }
    }
    return null;
};

buildSchema.methods.getEcoBuildList = function () {
    return this.eco_build_list;
};

buildSchema.methods.getDefBuildList = function () {
    return this.def_build_list;
};

/**
 * 获取建筑列表
 * @param  {[type]} build_id [description]
 * @return {[type]}          [description]
 */
buildSchema.methods.getBuildList = function (build_use_type) {
    build_use_type = +build_use_type;
    if (build_use_type == buildUseType.ECO) {
        return this.getEcoBuildList();
    } else {
        return this.getDefBuildList();
    }
};

/**
 * 获取建筑列表
 * @param  {[type]} build_type [description]
 * @return {[type]}            [description]
 */
buildSchema.methods.getBuildListByType = function (build_type) {
    var build_list = [];
    var build_use_type = buildConf.getBuildUseType(build_type);
    _.each(this.getBuildList(build_use_type), function (build_item) {
        var type = buildTypeUtil.getBuildType(build_item.build_id);
        if (type == build_type) {
            build_list.push(build_item);
        }
    });
    return build_list;
};

/**
 * 返回第一个指定类型的建筑
 * @param  {[type]} build_id [description]
 * @return {[type]}          [description]
 */
buildSchema.methods.getBuildByType = function (build_type) {
    var build_use_type = buildConf.getBuildUseType(build_type);
    var build_list = this.getBuildList(build_use_type);
    for (var i = 0; i < build_list.length; i++) {
        var build = build_list[i];
        var type = buildTypeUtil.getBuildType(build.build_id);
        if (type == build_type) {
            return build;
        }
    }
    return null;
};

/**
 * 获取当前城防中塔和障碍的数量（用于判断最大数）
 * @param  {[type]} build_id [description]
 * @return {[type]}          [description]
 */
buildSchema.methods.getDefBuildMaxNum = function (build_type) {
    var nexus_lvl = this.getBuildByType(buildType.NEXUS).getLv();
    return buildConf.getDefBuildMaxNum(nexus_lvl, build_type);
};

/**
 * 添加排程
 */
buildSchema.methods.addBuildSchedule = function (build_id, need_time) {
    var build = this.getBuild(build_id);
    if (!build) {
        return false;
    }
    var build_schedule = this.getBuildSchedule(build_id);
    if (!!build_schedule) {
        return false;
    }
    var end_time = moment().add(need_time, 's');
    this.build_schedule_list.push({
        build_id: build_id,
        end_time: end_time
    });
    return true;
};

/**
 * 设置排程
 */
buildSchema.methods.setBuildSchedule = function (build_id, quick_time) {
    var build = this.getBuild(build_id);

    if (!build) {
        return false;
    }
    var build_schedule = this.getBuildSchedule(build_id);

    if (!build_schedule) {
        return false;
    }

    var end_time = build_schedule.getEndTime();
    build_schedule.setEndTime(moment(end_time).add(-quick_time, 's'));
    return true;
};

/**
 * 获取排程列表
 * @return {[type]} [description]
 */
buildSchema.methods.getBuildScheduleList = function () {
    return this.build_schedule_list;
};

/**
 * 建筑道具加速
 * @return {[type]} [description]
 */
buildSchema.methods.buildConsumeTime = function (cb) {
    _.each(this.build_schedule_list, cb);
};

/**
 * 获取排程
 */
buildSchema.methods.getBuildSchedule = function (build_id) {
    for (var i = 0; i < this.build_schedule_list.length; i++) {
        var build_schedule = this.build_schedule_list[i];
        if (build_schedule.build_id == build_id) {
            return build_schedule;
        }
    }
    return null;
};

/**
 * 建筑类型的排程数量
 * @param  {[type]} build_id [description]
 * @return {[type]}          [description]
 */
buildSchema.methods.getBuildScheduleListByType = function (build_type) {
    var schedule_list = [];
    for (var i = 0; i < this.build_schedule_list.length; i++) {
        var build_schedule = this.build_schedule_list[i];
        if (buildTypeUtil.getBuildType(build_schedule.build_id) == build_type) {
            schedule_list.push(build_schedule);
        }
    }
    return schedule_list;
};

/**
 * 移除排程
 */
buildSchema.methods.removeBuildSchedule = function (build_id) {
    var build_schedule = this.getBuildSchedule(build_id);

    if (!build_schedule) {
        return false;
    }
    build_schedule.remove();
    return true;
};

/**
 * 升级建筑
 */
buildSchema.methods.upgradeBuild = function (build_id) {
    var build = this.getBuild(build_id);
    if (!build) {
        return false;
    }
    var ret_val = build.upgrade();

    return ret_val;
};

/**
 * 移动建筑
 */
buildSchema.methods.moveBuild = function (build_id, cell) {
    var build = this.getBuild(build_id);
    if (!build) {
        return false;
    }
    build.move(cell);
    return true;
};

/**
 * 获取路列表
 * @param {[type]} road_list [description]
 */
buildSchema.methods.getRoadList = function () {
    return this.road_list;
};

/**
 * 设置路列表
 * @param {[type]} road_list [description]
 */
buildSchema.methods.setRoadList = function (road_list) {
    this.road_list = road_list;
};

/**
 * 验证路径是否合法
 */
buildSchema.methods.checkPath = function () {
    // 判断路的长度是否走过最大路的个数
    var nexus_build = this.getBuildByType(buildType.NEXUS);
    var build_lv_conf = buildConf.getBuildLvConf(buildType.NEXUS, nexus_build.getLv());
    if (this.road_list.length > build_lv_conf.road_num) {
        return false;
    }

    // 验证道路是否有效
    var def_build_list = [];
    var def_block_list = [];

    for (var i = 0; i < this.def_build_list.length; i++) {
        var build = this.def_build_list[i];
        if (build.getBuildType() == buildType.ROAD_BLOCK ||
            build.getBuildType() == buildType.LANDMINE) {
            def_block_list.push(build.cell);
        } else {
            def_build_list.push(build.cell);
            if (build.cell === undefined) {
                def_build_list = [];
            }
        }
    }
    return buildCheck.isValid(def_build_list, def_block_list, this.road_list, this.ruin_list);
};

/**
 * 根据建筑类型获取列表
 */
buildSchema.methods.getEcoBuildNum = function (build_type) {
    var num = 0;
    for (var i = 0; i < this.eco_build_list.length; i++) {
        var build = this.eco_build_list[i];
        if (buildTypeUtil.getBuildType(build.build_id) == build_type) {
            num++;
        }
    }
    return num;
};

/**
 * 防御建筑个数创建
 * @param  {[type]} build_id [description]
 * @return {[type]}          [description]
 */
buildSchema.methods.getDefBuildId = function (build_type) {
    var num = 0;
    var list = [];
    var bag_def_build_list = this.getBagDefBuidingList();
    var def_build_list = this.getDefBuildList();
    _.each(bag_def_build_list, function (value) {
        list.push(value);
    });
    _.each(def_build_list, function (value) {
        list.push(value);
    });
    for (var i = 0; i < list.length; i++) {
        var build = list[i];
        var def_build_type = parseInt(build.build_id / 100);
        if (def_build_type == build_type) {
            num++;
        }
    }
    return num;
};

/**
 * 获取防御类建筑个数
 * @param  {[type]} build_type [description]
 * @return {[type]}            [description]
 */
buildSchema.methods.getBuildNum = function (build_type) {
    // var tower_num = 0;
    // var def_build_list = this.getDefBuildList();

    // for (var i = 0; i < def_build_list.length; i++) {
    //     var build = def_build_list[i];

    //     // 获取数据库中建筑个数
    //     var def_build_type = parseInt(build.build_id / 100);
    //     var build_type_type = dataApi.building_type.findById(def_build_type).type;

    //     // 防御塔个数
    //     if (build_type_type == 1) {
    //         tower_num++;
    //     }
    // }

    // //根据当前的建筑类型返回同类型个数
    // var now_build_type_type = dataApi.building_type.findById(build_type).type;
    // if (now_build_type_type == 1) {
    //     return tower_num;
    // }
    return this.getDefBuildList().length;
};

/**
 * 获取每种建筑的建造限制
 */
buildSchema.methods.getBuildMaxNum = function (build_type) {
    var nexus = this.getBuildByType(buildType.NEXUS);
    if (!nexus) {
        throw new Error('nexus is null');
    }

    return buildConf.getBuildMaxNum(nexus.lv, build_type);
};

/**
 * 清除废墟
 * @param  {[type]} ruin_id [description]
 * @return {[type]}         [description]
 */
buildSchema.methods.clearRuin = function (ruin_id) {
    if (_.indexOf(this.ruin_list, ruin_id) == -1) {
        return false;
    }
    this.ruin_list = _.without(this.ruin_list, ruin_id);
    return true;
};

/**
 * 获取最大的金币存储上限
 * @return {[type]} [description]
 */
buildSchema.methods.getMaxGoldStore = function () {
    // var chest_build = this.getBuildByType(buildType.CHEST);
    // if (!chest_build || chest_build.lv <= 0) {
    //     return 0;
    // }

    // // 获取金库的配置
    // var chest_lv_conf = buildConf.getBuildLvConf(buildType.CHEST, chest_build.lv);
    // if (!chest_lv_conf) {
    //     return 0;
    // }
    // return chest_lv_conf.gold_store_num;
    return 2000000000;
};

/**
 * 获取最大的粮食存储上限
 * @return {[type]} [description]
 */
buildSchema.methods.getMaxFoodStore = function () {
    // var barn_build = this.getBuildByType(buildType.BARN);
    // if (!barn_build || barn_build.lv <= 0) {
    //     return 0;
    // }

    // var barn_lv_conf = buildConf.getBuildLvConf(buildType.BARN, barn_build.lv);
    // if (!barn_lv_conf) {
    //     return 0;
    // }
    // return barn_lv_conf.food_store_num;
    return 2000000000;
};

/**
 * 塔的数量
 * @return {[type]} [description]
 */
buildSchema.methods.getTowerNum = function () {
    var tower_num = 0;
    _.each(this.def_build_list, function (def_build_item) {
        if (buildTypeUtil.isTower(def_build_item.getBuildType())) {
            tower_num++;
        }
    });
    return tower_num;
};

mongoose.model('Build', buildSchema);
